package com.junqi.msg.event.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.junqi.common.entity.RedisKeyManager;
import com.junqi.msg.adapter.WSAdapter;
import com.junqi.msg.event.UserPushMsgEvent;
import com.junqi.msg.service.WebSocketService;
import com.junqi.msg.utils.JsonUtils;
import com.junqi.msg.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Set;


/**
 * 用户推送新消息事件监听
 */
@Component
public class UserPushMsgListener {

    @Autowired
    private WebSocketService webSocketService;
    @Autowired
    private WSAdapter wsAdapter;
    private static final long PULL_INTERVAL = 3000L; // 拉取间隔限制 3 秒

    @Async
    @EventListener(classes = UserPushMsgEvent.class)
    public void pushMsg(UserPushMsgEvent event) {
        String roomId = event.getRoomId();//房间id

        /**********************************  通知合并机制 上 将所有成员加入到待通知队列中（如已存在则更新通知消息时间，具有拉取中标记，如果距设置标记时间在 2 秒内则不会下发通知）； *******************************/

        //获取房间缓存中的用户
        Set<String> userSet = RedisUtil.sGet(RedisKeyManager.generateKey(RedisKeyManager.ROOM_USERS, roomId));
        if(CollUtil.isNotEmpty(userSet)){
            long timestamp = System.currentTimeMillis();
            for (String userId : userSet) {
                Object hget = RedisUtil.hget(RedisKeyManager.generateKey(RedisKeyManager.WS_NOTIF_QUEUE_USERS), userId);
                //检查用户拉取状态 + 已通知时间在 3 秒内，丢弃通知，消息合并
                if (hget!=null && (timestamp - Long.valueOf((String)hget) < PULL_INTERVAL)) {
                    // 如果在 2 秒内，丢弃通知，但消息合并
                    //System.out.println("Dropping notification for user: " + userId);
                    continue;
                }
                //System.out.println("用户推送新消息事件监听:userId="+userId+",hget="+hget+",当前时间="+ DateUtil.formatDateTime(new Date()));
                // 更新 Redis 用户状态，添加用户到待通知队列
                RedisUtil.hset(RedisKeyManager.generateKey(RedisKeyManager.WS_NOTIF_QUEUE_USERS),userId,timestamp);
                /***********************************  通知合并机制 中 向队列中用户下发通知拉取 *******************************/
                // 遍历用户并发送通知
                webSocketService.sendMessageToUid(JsonUtils.toStr(wsAdapter.buildMsgNotifyResp()),userId);
            }
        }
    }

}
